/**
 * Software License, Version 1.0
 * 
 * Copyright 2003 The Trustees of Indiana University.  All rights reserved.
 * 
 *
 *Redistribution and use in source and binary forms, with or without 
 *modification, are permitted provided that the following conditions are met:
 *
 *1) All redistributions of source code must retain the above copyright notice,
 * the list of authors in the original source code, this list of conditions and
 * the disclaimer listed in this license;
 *2) All redistributions in binary form must reproduce the above copyright 
 * notice, this list of conditions and the disclaimer listed in this license in
 * the documentation and/or other materials provided with the distribution;
 *3) Any documentation included with all redistributions must include the 
 * following acknowledgement:
 *
 *"This product includes software developed by the Community Grids Lab. For 
 * further information contact the Community Grids Lab at 
 * http://communitygrids.iu.edu/."
 *
 * Alternatively, this acknowledgement may appear in the software itself, and 
 * wherever such third-party acknowledgments normally appear.
 * 
 *4) The name Indiana University or Community Grids Lab or NaradaBrokering, 
 * shall not be used to endorse or promote products derived from this software 
 * without prior written permission from Indiana University.  For written 
 * permission, please contact the Advanced Research and Technology Institute 
 * ("ARTI") at 351 West 10th Street, Indianapolis, Indiana 46202.
 *5) Products derived from this software may not be called NaradaBrokering, 
 * nor may Indiana University or Community Grids Lab or NaradaBrokering appear
 * in their name, without prior written permission of ARTI.
 * 
 *
 * Indiana University provides no reassurances that the source code provided 
 * does not infringe the patent or any other intellectual property rights of 
 * any other entity.  Indiana University disclaims any liability to any 
 * recipient for claims brought by any other entity based on infringement of 
 * intellectual property rights or otherwise.  
 *
 *LICENSEE UNDERSTANDS THAT SOFTWARE IS PROVIDED "AS IS" FOR WHICH NO 
 *WARRANTIES AS TO CAPABILITIES OR ACCURACY ARE MADE. INDIANA UNIVERSITY GIVES
 *NO WARRANTIES AND MAKES NO REPRESENTATION THAT SOFTWARE IS FREE OF 
 *INFRINGEMENT OF THIRD PARTY PATENT, COPYRIGHT, OR OTHER PROPRIETARY RIGHTS. 
 *INDIANA UNIVERSITY MAKES NO WARRANTIES THAT SOFTWARE IS FREE FROM "BUGS", 
 *"VIRUSES", "TROJAN HORSES", "TRAP DOORS", "WORMS", OR OTHER HARMFUL CODE.  
 *LICENSEE ASSUMES THE ENTIRE RISK AS TO THE PERFORMANCE OF SOFTWARE AND/OR 
 *ASSOCIATED MATERIALS, AND TO THE PERFORMANCE AND VALIDITY OF INFORMATION 
 *GENERATED USING SOFTWARE.
 */
package cgl.narada.wsinfra.util;

import javax.xml.namespace.QName;

import org.apache.xmlbeans.XmlObject;

import cgl.narada.wsinfra.exception.WsFaultException;
import cgl.narada.wsinfra.schemas.addressing.EndpointReferenceType;
import cgl.narada.wsinfra.schemas.soap.EnvelopeDocument;

/** This is a utility class which performs the conversion of a WsFaultException
    into a SOAP fault.

    @author Shrideep Pallickara
    $Date: 2005/07/29 22:41:29 $
    $Revision: 1.4 $
*/

public class ExceptionToFaultConversion {
  private static final ExceptionToFaultConversion instance =
  new ExceptionToFaultConversion();
  private FaultCreator faultCreator;
  private SoapMessageAlteration soapMessageAlteration;

  private String moduleName = "ExceptionToFaultConversion: ";

  private ExceptionToFaultConversion() {
    faultCreator = FaultCreator.getInstance();
    soapMessageAlteration = SoapMessageAlteration.getInstance();
  }

  public static ExceptionToFaultConversion getInstance() {
    return instance;
  }


  /** This returns a NULL if either the faulTo or the faultCodeQName in the
      wsFaultException is null. The method also returns an error */
  public EnvelopeDocument
  convertToSOAPFault(WsFaultException wsFaultException) {
    QName faultCodeQName = wsFaultException.getFaultCodeQName();
    String reason = wsFaultException.getReason();
    if (reason == null) {
      reason="";
    }

    EndpointReferenceType faultTo = wsFaultException.getFaultTo();

    if (faultCodeQName == null || faultTo == null) {
      return null;
    }

    boolean hasFaultActor = wsFaultException.hasFaultActor();
    boolean hasDetailObject = wsFaultException.hasDetailObject();

    EnvelopeDocument faultDocument = null;

    if (!hasFaultActor && !hasDetailObject) {
      faultDocument = faultCreator.createFault(faultCodeQName, reason,
					       faultTo);
      processFaultDocumentHeader(faultDocument, wsFaultException);
      return faultDocument;
    }

    if (hasFaultActor && !hasDetailObject) {
      faultDocument =
	faultCreator.createFault(faultCodeQName, reason,
				 wsFaultException.getFaultActor(), faultTo);
      processFaultDocumentHeader(faultDocument, wsFaultException);
      return faultDocument;
    }

    if (!hasFaultActor && hasDetailObject) {
      faultDocument =
	faultCreator.createFault(faultCodeQName, reason,
				 wsFaultException.getDetailObject(), faultTo);
      processFaultDocumentHeader(faultDocument, wsFaultException);
      return faultDocument;

    }


    if (hasFaultActor && hasDetailObject) {
      faultDocument =
	faultCreator.createFault(faultCodeQName, reason,
				 wsFaultException.getDetailObject(),
				 wsFaultException.getFaultActor(), faultTo);
      processFaultDocumentHeader(faultDocument, wsFaultException);
      return faultDocument;
    }
 
    return faultDocument;
  }

  /** This checks to see if the exception includes elements that need to be
      added to the SOAP header */
  private void 
  processFaultDocumentHeader(EnvelopeDocument faultDocument, 
			     WsFaultException wsFaultException) {
    if (faultDocument == null) {
      return;
    }
    
    if (! wsFaultException.hasAddSoapHeaderElement()) {
      return;
    }

    /** Process the element that needs to be added to the SOAP header */
    XmlObject headerElement = wsFaultException.getAddSoapHeaderElement();
    soapMessageAlteration.addToSoapHeader(faultDocument, headerElement);
  }

}

